/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.user.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.api.ApiCode;
import co.yixiang.api.UnAuthenticatedException;
import co.yixiang.api.YshopException;
import co.yixiang.common.service.impl.BaseServiceImpl;
import co.yixiang.common.utils.QueryHelpPlus;
import co.yixiang.constant.ShopConstants;
import co.yixiang.constant.SystemConfigConstants;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.enums.BillDetailEnum;
import co.yixiang.enums.Brokerage;
import co.yixiang.enums.OrderInfoEnum;
import co.yixiang.enums.ShopCommonEnum;
import co.yixiang.event.TemplateBean;
import co.yixiang.event.TemplateEvent;
import co.yixiang.event.TemplateListenEnum;
import co.yixiang.modules.activity.service.YxStoreCouponUserService;
import co.yixiang.modules.cart.vo.YxStoreCartQueryVo;
import co.yixiang.modules.order.domain.YxStoreOrder;
import co.yixiang.modules.order.domain.YxStoreOrderCartInfo;
import co.yixiang.modules.order.service.YxStoreOrderCartInfoService;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.order.service.mapper.StoreOrderMapper;
import co.yixiang.modules.order.vo.YxStoreOrderQueryVo;
import co.yixiang.modules.product.vo.YxStoreProductQueryVo;
import co.yixiang.modules.shop.domain.YxSystemUserLevel;
import co.yixiang.modules.shop.service.YxSystemConfigService;
import co.yixiang.modules.shop.service.YxSystemStoreStaffService;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.domain.YxUserLevel;
import co.yixiang.modules.user.service.YxSystemUserLevelService;
import co.yixiang.modules.user.service.YxUserBillService;
import co.yixiang.modules.user.service.YxUserLevelService;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.dto.*;
import co.yixiang.modules.user.service.mapper.UserBillMapper;
import co.yixiang.modules.user.service.mapper.UserMapper;
import co.yixiang.modules.user.vo.TotalDataQueryVo;
import co.yixiang.modules.user.vo.YxUserQueryVo;
import co.yixiang.utils.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author hupeng
* @date 2020-05-12
*/
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxUserServiceImpl extends BaseServiceImpl<UserMapper, YxUser> implements YxUserService {

    @Autowired
    private IGenerator generator;

    @Autowired
    private UserMapper yxUserMapper;
    @Autowired
    private StoreOrderMapper storeOrderMapper;
    @Autowired
    private UserBillMapper userBillMapper;


    @Autowired
    private YxSystemUserLevelService systemUserLevelService;
    @Autowired
    private YxUserLevelService userLevelService;
    @Autowired
    private YxStoreOrderService orderService;
    @Autowired
    private YxSystemConfigService systemConfigService;
    @Autowired
    private YxUserBillService billService;
    @Autowired
    private YxStoreCouponUserService storeCouponUserService;
    @Autowired
    private YxSystemStoreStaffService systemStoreStaffService;
    @Autowired
    private YxStoreOrderCartInfoService storeOrderCartInfoService;

    @Autowired
    private ApplicationEventPublisher publisher;


    /**
     * 返回用户累计充值金额与消费金额
     * @param uid uid
     * @return Double[]
     */
    @Override
    public Double[] getUserMoney(Long uid){
        double sumPrice = storeOrderMapper.sumPrice(uid);
        double sumRechargePrice = userBillMapper.sumRechargePrice(uid);
        return new Double[]{sumPrice,sumRechargePrice};
    }


    /**
     * 增加购买次数
     * @param uid uid
     */
    @Override
    public void incPayCount(Long uid) {
        yxUserMapper.incPayCount(uid);
    }

    /**
     * 增加抽奖次数
     * @param uid uid
     */
    @Override
    public void incPrizeCount(Long uid,int prizeCount) {
        yxUserMapper.incPrizeCount(uid,prizeCount);
    }

    /**
     * 减去用户余额
     * @param uid uid
     * @param payPrice 金额
     */
    @Override
    public void decPrice(Long uid, BigDecimal payPrice) {
        yxUserMapper.decPrice(payPrice,uid);
        YxUser user =this.getById(uid);
        log.info("用户user===="+user);
        /*TemplateBean templateBean = TemplateBean.builder()
                .orderId(payPrice.toString())
                .price(user.getNowMoney().toString())
                .uid(uid)
                .templateType(TemplateListenEnum.TYPE_10.getValue())
                .time(DateUtil.formatDateTime(new Date()))
                .payType("积分减少")
                .build();
        publisher.publishEvent(new TemplateEvent(this,templateBean));*/
    }

    /**
     * 减去用户积分
     * @param uid 用户id
     * @param integral 积分
     */
    @Override
    public void decIntegral(Long uid, double integral) {
        yxUserMapper.decIntegral(integral,uid);
    }


    /**
     * 获取我的分销下人员列表
     * @param uid uid
     * @param page page
     * @param limit limit
     * @param grade ShopCommonEnum.GRADE_0
     * @param keyword 关键字搜索
     * @param sort 排序
     * @return list
     */
    @Override
    public List<PromUserDto> getUserSpreadGrade(Long uid, int page, int limit, Integer grade,
                                                String keyword, String sort) {
        List<YxUser> userList = yxUserMapper.selectList(Wrappers.<YxUser>lambdaQuery()
                .eq(YxUser::getSpreadUid, uid));
        List<Long> userIds = userList.stream()
                .map(YxUser::getUid)
                .collect(Collectors.toList());

        List<PromUserDto> list = new ArrayList<>();
        if (userIds.isEmpty()) {
            return list;
        }

        if (StrUtil.isBlank(sort)) {
            sort = "u.uid desc";
        }

        Page<YxUser> pageModel = new Page<>(page, limit);
        if (ShopCommonEnum.GRADE_0.getValue().equals(grade)) {//-级
            list = yxUserMapper.getUserSpreadCountList(pageModel, userIds,
                    keyword, sort);
        } else {//二级
            List<YxUser> userListT = yxUserMapper.selectList(Wrappers.<YxUser>lambdaQuery()
                    .in(YxUser::getSpreadUid, userIds));
            List<Long> userIdsT = userListT.stream()
                    .map(YxUser::getUid)
                    .collect(Collectors.toList());
            if (userIdsT.isEmpty()) {
                return list;
            }
            list = yxUserMapper.getUserSpreadCountList(pageModel, userIdsT,
                    keyword, sort);

        }
        return list;
    }

    /**
     * 获取我的分销下人员列表(新)
     * @param uid uid
     * @param page page
     * @param limit limit
     * @param grade ShopCommonEnum.GRADE_0
     * @param keyword 关键字搜索
     * @param sort 排序
     * @return list
     */
    @Override
    public List<PromUserDto> getUserSpreadGrade4new(Long uid, int page, int limit, Integer grade,
                                                String keyword, String sort,Integer level) {
        List<YxUser> userList = yxUserMapper.selectList(Wrappers.<YxUser>lambdaQuery()
                .eq(YxUser::getSpreadUid, uid));
        List<Long> userIds = userList.stream()
                .map(YxUser::getUid)
                .collect(Collectors.toList());

        List<PromUserDto> list = new ArrayList<>();
        if (userIds.isEmpty()) {
            return list;
        }

        if (StrUtil.isBlank(sort)) {
            sort = "u.uid desc";
        }

        Page<YxUser> pageModel = new Page<>(page, limit);
        list = yxUserMapper.getUserSpreadCountList4new(pageModel, userIds,
                keyword, sort,level);

        return list;
    }

    /**
     * 统计分销人员
     * @param uid uid
     * @return map
     */
    @Override
    public Map<String,Integer> getSpreadCount(Long uid) {
        int countOne = yxUserMapper.selectCount(Wrappers.<YxUser>lambdaQuery()
                .eq(YxUser::getSpreadUid,uid));

        int countTwo = 0;
        List<YxUser> userList = yxUserMapper.selectList((Wrappers.<YxUser>lambdaQuery()
                .eq(YxUser::getSpreadUid,uid)));
        List<Long> userIds = userList.stream().map(YxUser::getUid)
                .collect(Collectors.toList());
        if(!userIds.isEmpty()){
            countTwo = yxUserMapper.selectCount(Wrappers.<YxUser>lambdaQuery()
                    .in(YxUser::getSpreadUid,userIds));
        }

        Map<String,Integer> map = new LinkedHashMap<>(2);
        map.put("first",countOne); //一级
        map.put("second",countTwo);//二级

        return map;
    }

    /**
     * 统计分销人员(新)
     * @param uid uid
     * @return map
     */
    @Override
    public Map<String,Object> getSpreadCount4new(Long uid) {
        String activityBeginTime = systemConfigService.getData(ShopConstants.ACTIVITY_BEGIN_TIME);
        String activityEndTime = systemConfigService.getData(ShopConstants.ACTIVITY_END_TIME);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if(ObjectUtil.isNotEmpty(activityBeginTime)){
            Date date = null;
            try {
                // 注意格式需要与上面一致，不然会出现异常
                date = sdf.parse(activityBeginTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            activityBeginTime =sdf.format(date);
        }
        if(ObjectUtil.isNotEmpty(activityEndTime)){
            Date date = null;
            try {
                // 注意格式需要与上面一致，不然会出现异常
                date = sdf.parse(activityEndTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            activityEndTime =sdf.format(date);
        }
        List<HashMap<String,Object>> result = yxUserMapper.getChildrensCount(uid,activityBeginTime,activityEndTime);

        Map<String,Object> map = new LinkedHashMap<>(2);
        for(int i = 0;i<result.size();i++) {
            Map item = result.get(i);
            /*if("vip_total_sum".equals(item.get("TYPE").toString())){
                map.put(item.get("TYPE").toString(),new BigDecimal(item.get("COUNT").toString()));
            }else{
                map.put(item.get("TYPE").toString(),item.get("COUNT"));
            }*/
            map.put(item.get("TYPE").toString(),item.get("COUNT"));
        }
        return map;
    }

    /**
     * 一级返佣
     * @param order 订单
     */
    @Override
    public void backOrderBrokerage(YxStoreOrderQueryVo order) {
        //如果分销没开启直接返回
        String open = systemConfigService.getData(SystemConfigConstants.STORE_BROKERAGE_OPEN);
        if(StrUtil.isBlank(open) || ShopCommonEnum.ENABLE_2.getValue().toString().equals(open)) {
            return;
        }


        //获取购买商品的用户
        YxUser userInfo =  this.getById(order.getUid());
        System.out.println("userInfo:"+userInfo);
        //当前用户不存在 没有上级  直接返回
        if(ObjectUtil.isNull(userInfo) || userInfo.getSpreadUid() == 0) {
            return;
        }


        YxUser preUser = this.getById(userInfo.getSpreadUid());

        //一级返佣金额
        BigDecimal brokeragePrice = this.computeProductBrokerage(order, Brokerage.LEVEL_1);

        //返佣金额小于等于0 直接返回不返佣金

        if(brokeragePrice.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }

        //计算上级推广员返佣之后的金额
        double balance = NumberUtil.add(preUser.getBrokeragePrice(),brokeragePrice).doubleValue();
        String mark = userInfo.getNickname()+"成功消费"+order.getPayPrice()+"元,奖励推广佣金"+
                brokeragePrice;
        //增加流水
        billService.income(userInfo.getSpreadUid(),"获得推广佣金",BillDetailEnum.CATEGORY_1.getValue(),
                BillDetailEnum.TYPE_2.getValue(),brokeragePrice.doubleValue(),balance, mark,order.getId().toString());

        //添加用户余额
        yxUserMapper.incBrokeragePrice(brokeragePrice, userInfo.getSpreadUid());

        //一级返佣成功 跳转二级返佣
        this.backOrderBrokerageTwo(order);

    }




    /**
     * 更新用户余额
     * @param uid y用户id
     * @param price 金额
     */
    @Override
    public void incMoney(Long uid, BigDecimal price) {

        yxUserMapper.incMoney(uid,price);
        /*YxUser user =this.getById(uid);
        TemplateBean templateBean = TemplateBean.builder()
                .orderId(price.toString())
                .price(user.getNowMoney().toString())
                .uid(uid)
                .templateType(TemplateListenEnum.TYPE_10.getValue())
                .time(DateUtil.formatDateTime(new Date()))
                .payType("积分增加")
                .build();
        publisher.publishEvent(new TemplateEvent(this,templateBean));*/
    }

    /**
     * 增加积分
     * @param uid uid
     * @param integral 积分
     */
    @Override
    public void incIntegral(Long uid, double integral) {
        yxUserMapper.incIntegral(integral,uid);
    }


    /**
     * 获取用户信息
     * @param uid uid
     * @return YxUserQueryVo
     */
    @Override
    public YxUserQueryVo getYxUserById(Long uid) {
        return generator.convert(this.getById(uid),YxUserQueryVo.class);
    }


    /**
     * 转换用户信息
     * @param yxUser user
     * @return YxUserQueryVo
     */
    @Override
    public YxUserQueryVo handleUser(YxUser yxUser) {
        return generator.convert(yxUser,YxUserQueryVo.class);
    }

    /**
     * 获取用户个人详细信息
     * @param yxUser yxUser
     * @return YxUserQueryVo
     */
    @Override
    public YxUserQueryVo getNewYxUserById(YxUser yxUser) {
        log.info("========yxUser======"+yxUser);
        YxUserQueryVo userQueryVo = generator.convert(yxUser,YxUserQueryVo.class);
        if(userQueryVo == null){
            throw new UnAuthenticatedException(ApiCode.UNAUTHORIZED);
        }
        YxSystemUserLevel systemUserLevelQueryVo = new YxSystemUserLevel();
        if(yxUser.getLevel().intValue() ==0){
            systemUserLevelQueryVo = systemUserLevelService
                    .getById(new Long(7));
        }else{
            systemUserLevelQueryVo = systemUserLevelService
                    .getById(yxUser.getLevel());
        }
        userQueryVo.setOrderStatusNum(orderService.orderData(yxUser.getUid()));
        userQueryVo.setCouponCount(storeCouponUserService.getUserValidCouponCount(yxUser.getUid()));
        if(systemUserLevelQueryVo != null){
            userQueryVo.setVip(true);
            userQueryVo.setVipId(systemUserLevelQueryVo.getId());
            userQueryVo.setVipIcon(systemUserLevelQueryVo.getIcon());
            userQueryVo.setVipName(systemUserLevelQueryVo.getName());
        }
        //判断分销类型,指定分销废弃掉，只有一种分销方式
        /**
            String statu = systemConfigService.getData(SystemConfigConstants.STORE_BROKERAGE_STATU);
            if(StrUtil.isNotEmpty(statu)){
                userQueryVo.setStatu(Integer.valueOf(statu));
            }else{
                userQueryVo.setStatu(0);
            }
         **/

        //获取核销权限
        userQueryVo.setCheckStatus(systemStoreStaffService.checkStatus(yxUser.getUid(),null));
        log.info("========yxUser1111111======"+yxUser);
        //this.setUserSpreadCount(yxUser);
        return userQueryVo;
    }



    /**
     * 返回会员价
     * @param price 原价
     * @param uid 用户id
     * @return vip 价格
     */
    @Override
    public double setLevelPrice(double price, long uid) {
       LambdaQueryWrapper<YxUserLevel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YxUserLevel::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())
                .eq(YxUserLevel::getUid,uid)
                .orderByDesc(YxUserLevel::getGrade)
                .last("limit 1");
        YxUserLevel userLevel = userLevelService.getOne(wrapper);
        YxSystemUserLevel systemUserLevel = new YxSystemUserLevel();
        if(ObjectUtil.isNotNull(userLevel)) {
            systemUserLevel=  systemUserLevelService.getById(userLevel.getLevelId());
        }
        int discount = 100;
        if(ObjectUtil.isNotNull(userLevel)) {
            discount = systemUserLevel.getDiscount().intValue();
        }
        return NumberUtil.mul(NumberUtil.div(discount,100),price);
    }


    /**
     * 设置推广关系
     * @param spread 上级人
     * @param uid 本人
     */
    @Override
    public void setSpread(String spread, long uid) {
        log.info("spread====="+spread);
        if(StrUtil.isBlank(spread) || !NumberUtil.isNumber(spread)) {
            return;
        }
        log.info("uid====="+uid);
        if(uid ==666) {
            return;
        }
        log.info("spread1111111111111====="+spread);
        //如果分销没开启直接返回
        String open = systemConfigService.getData(SystemConfigConstants.STORE_BROKERAGE_OPEN);
        if(StrUtil.isBlank(open) || ShopCommonEnum.ENABLE_2.getValue().toString().equals(open)) {
            return;
        }
        log.info("open====="+open);
        //当前用户信息
        YxUser userInfo = this.getById(uid);
        if(ObjectUtil.isNull(userInfo)) {
            return;
        }
        log.info("userInfo1111111111111====="+userInfo);
        //当前用户有上级直接返回
        if(userInfo.getSpreadUid() != null && userInfo.getSpreadUid() > 0) {
            return;
        }
        //没有推广编号直接返回
        long spreadInt = Long.valueOf(spread);
        if(spreadInt == 0) {
            return;
        }
        if(spreadInt == uid) {
            return;
        }
        log.info("2222222222222222====="+userInfo);
        //不能互相成为上下级
        YxUser userInfoT = this.getById(spreadInt);
        if(ObjectUtil.isNull(userInfoT)) {
            return;
        }
        log.info("3333333333333====="+userInfo);
        if(userInfoT.getSpreadUid() == uid) {
            return;
        }

        YxUser yxUser = YxUser.builder()
                .spreadUid(spreadInt)
                .spreadTime(new Date())
                .uid(uid)
                .build();
        log.info("yxUser1111111111111====="+yxUser);
        yxUserMapper.updateById(yxUser);
        log.info("yxUser22222====="+this.getById(uid));
    }


    /**
     * 二级返佣
     * @param order 订单
     */
    private void backOrderBrokerageTwo(YxStoreOrderQueryVo order) {

        YxUser userInfo =  this.getById(order.getUid());

        //获取上推广人
        YxUser userInfoTwo = this.getById(userInfo.getSpreadUid());

        //上推广人不存在 或者 上推广人没有上级    直接返回
        if(ObjectUtil.isNull(userInfoTwo) || userInfoTwo.getSpreadUid() == 0) {
            return;
        }


        //指定分销 判断 上上级是否时推广员  如果不是推广员直接返回
        YxUser preUser = this.getById(userInfoTwo.getSpreadUid());


        //二级返佣金额
        BigDecimal brokeragePrice = this.computeProductBrokerage(order,Brokerage.LEVEL_2);

        //返佣金额小于等于0 直接返回不返佣金
        if(brokeragePrice.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }

        //获取上上级推广员信息
        double balance = NumberUtil.add(preUser.getBrokeragePrice(),brokeragePrice).doubleValue();
        String mark = "二级推广人"+userInfo.getNickname()+"成功消费"+order.getPayPrice()+"元,奖励推广佣金"+
                brokeragePrice;

        //增加流水
        billService.income(userInfoTwo.getSpreadUid(),"获得推广佣金",BillDetailEnum.CATEGORY_1.getValue(),
                BillDetailEnum.TYPE_2.getValue(),brokeragePrice.doubleValue(),balance, mark,order.getId().toString());
        //添加用户余额
        yxUserMapper.incBrokeragePrice(brokeragePrice,
                userInfoTwo.getSpreadUid());
    }


    /**
     * 计算获取返佣金额
     * @param order 订单信息
     * @param level 分销级别
     * @return double
     */
    private BigDecimal computeProductBrokerage(YxStoreOrderQueryVo order , Brokerage level){
        List<YxStoreOrderCartInfo> storeOrderCartInfoList = storeOrderCartInfoService
                .list(Wrappers.<YxStoreOrderCartInfo>lambdaQuery()
                        .in(YxStoreOrderCartInfo::getCartId, Arrays.asList(order.getCartId().split(","))));
        BigDecimal oneBrokerage = BigDecimal.ZERO;//一级返佣金额
        BigDecimal twoBrokerage = BigDecimal.ZERO;//二级返佣金额

        List<String> cartInfos = storeOrderCartInfoList.stream()
                .map(YxStoreOrderCartInfo::getCartInfo)
                .collect(Collectors.toList());

        for (String cartInfo : cartInfos){
            YxStoreCartQueryVo cart = JSON.parseObject(cartInfo,YxStoreCartQueryVo.class);

            YxStoreProductQueryVo storeProductVO = cart.getProductInfo();
            //产品是否单独分销
            if(ShopCommonEnum.IS_SUB_1.getValue().equals(storeProductVO.getIsSub())){
                oneBrokerage = NumberUtil.round(NumberUtil.add(oneBrokerage,
                        NumberUtil.mul(cart.getCartNum(),storeProductVO.getAttrInfo().getBrokerage()))
                        ,2);

                twoBrokerage = NumberUtil.round(NumberUtil.add(twoBrokerage,
                        NumberUtil.mul(cart.getCartNum(),storeProductVO.getAttrInfo().getBrokerageTwo()))
                        ,2);
            }

        }

        //获取后台一级返佣比例
        String storeBrokerageRatioStr = systemConfigService.getData(SystemConfigConstants.STORE_BROKERAGE_RATIO);
        String storeBrokerageTwoStr = systemConfigService.getData(SystemConfigConstants.STORE_BROKERAGE_TWO);


        //一级返佣比例未设置直接返回
        if(StrUtil.isBlank(storeBrokerageRatioStr)
                || !NumberUtil.isNumber(storeBrokerageRatioStr)){
            return oneBrokerage;
        }
        //二级返佣比例未设置直接返回
        if(StrUtil.isBlank(storeBrokerageTwoStr)
                || !NumberUtil.isNumber(storeBrokerageTwoStr)){
            return twoBrokerage;
        }


        switch (level){
            case LEVEL_1:
                //根据订单获取一级返佣比例
                BigDecimal storeBrokerageRatio = NumberUtil.round(NumberUtil.div(storeBrokerageRatioStr,"100"),2);
                BigDecimal brokeragePrice = NumberUtil
                        .round(NumberUtil.mul(order.getTotalPrice(),storeBrokerageRatio),2);
                //固定返佣 + 比例返佣 = 总返佣金额
                return NumberUtil.add(oneBrokerage,brokeragePrice);
            case LEVEL_2:
                //根据订单获取一级返佣比例
                BigDecimal storeBrokerageTwo = NumberUtil.round(NumberUtil.div(storeBrokerageTwoStr,"100"),2);
                BigDecimal storeBrokerageTwoPrice = NumberUtil
                        .round(NumberUtil.mul(order.getTotalPrice(),storeBrokerageTwo),2);
                //固定返佣 + 比例返佣 = 总返佣金额
                return NumberUtil.add(twoBrokerage,storeBrokerageTwoPrice);
        }


        return BigDecimal.ZERO;

    }



    /**
     * 更新下级人数
     * @param yxUser user
     */
    private void setUserSpreadCount(YxUser yxUser) {
        int count = yxUserMapper.selectCount(Wrappers.<YxUser>lambdaQuery()
                .eq(YxUser::getSpreadUid,yxUser.getUid()));
        yxUser.setSpreadCount(count);
        yxUserMapper.updateById(yxUser);
    }


    //===========后面管理后台部分=====================//


    /**
     * 查看下级
     * @param uid uid
     * @param grade 等级
     * @return list
     */
    @Override
    public List<PromUserDto> querySpread(Long uid, Integer grade) {
        return this.getUserSpreadGrade(uid,1, 10,grade,"","");
    }


    @Override
    public Map<String, Object> queryAll(YxUserQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<YxUser> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", generator.convert(page.getList(), YxUserDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }


    @Override
    //@Cacheable
    public List<YxUser> queryAll(YxUserQueryCriteria criteria){
        return yxUserMapper.findAllUserByQueryCriteria(criteria.getNickname(),criteria.getPhone(),criteria.getIsPromoter(),criteria.getUserType(),criteria.getIsOpen(),
                criteria.getUid(),criteria.getGrade(),criteria.getLevel());
        //return baseMapper.selectList(QueryHelpPlus.getPredicate(YxUser.class, criteria));
    }


    @Override
    public void download(List<YxUserDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YxUserDto yxUser : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("用户账户(跟accout一样)", yxUser.getUsername());
            map.put("用户密码（跟pwd）", yxUser.getPassword());
            map.put("真实姓名", yxUser.getRealName());
            map.put("生日", yxUser.getBirthday());
            map.put("身份证号码", yxUser.getCardId());
            map.put("用户备注", yxUser.getMark());
            map.put("合伙人id", yxUser.getPartnerId());
            map.put("用户分组id", yxUser.getGroupId());
            map.put("用户昵称", yxUser.getNickname());
            map.put("用户头像", yxUser.getAvatar());
            map.put("手机号码", yxUser.getPhone());
            map.put("添加时间", yxUser.getCreateTime());
            map.put("添加ip", yxUser.getAddIp());
            map.put("用户余额", yxUser.getNowMoney());
            map.put("佣金金额", yxUser.getBrokeragePrice());
            map.put("用户剩余积分", yxUser.getIntegral());
            map.put("连续签到天数", yxUser.getSignNum());
            map.put("1为正常，0为禁止", yxUser.getStatus());
            map.put("等级", yxUser.getLevel());
            map.put("推广元id", yxUser.getSpreadUid());
            map.put("推广员关联时间", yxUser.getSpreadTime());
            map.put("用户类型", yxUser.getUserType());
            map.put("是否为推广员", yxUser.getIsPromoter());
            map.put("用户购买次数", yxUser.getPayCount());
            map.put("下级人数", yxUser.getSpreadCount());
            map.put("详细地址", yxUser.getAddres());
            map.put("管理员编号 ", yxUser.getAdminid());
            map.put("用户登陆类型，h5,wechat,routine", yxUser.getLoginType());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 更新用户状态
     * @param uid uid
     * @param status ShopCommonEnum
     */
    @Override
    public void onStatus(Long uid, Integer status) {
        if(ShopCommonEnum.IS_STATUS_1.getValue().equals(status)){
            status = ShopCommonEnum.IS_STATUS_0.getValue();
        }else{
            status = ShopCommonEnum.IS_STATUS_1.getValue();
        }
        yxUserMapper.updateOnstatus(status,uid);
    }

    /**
     * 修改余额
     * @param param UserMoneyDto
     */
    @Override
    public void updateMoney(UserMoneyDto param) {
        YxUser yxUser = this.getById(param.getUid());
        double newMoney = 0d;
        String mark = "";
        String type ="积分增加";
        if(param.getPtype() == 1){
            mark = "系统增加了"+param.getMoney()+"余额";
            newMoney = NumberUtil.add(yxUser.getNowMoney(),param.getMoney()).doubleValue();
            billService.income(yxUser.getUid(),"系统增加余额", BillDetailEnum.CATEGORY_1.getValue(),
                    BillDetailEnum.TYPE_6.getValue(),param.getMoney(),newMoney, mark,"");
        }else{
            mark = "系统扣除了"+param.getMoney()+"余额";
            type ="积分减少";
            newMoney = NumberUtil.sub(yxUser.getNowMoney(),param.getMoney()).doubleValue();
            if(newMoney < 0) {
                newMoney = 0d;
            }
            billService.expend(yxUser.getUid(), "系统减少余额",
                    BillDetailEnum.CATEGORY_1.getValue(),
                    BillDetailEnum.TYPE_7.getValue(),
                    param.getMoney(), newMoney, mark);
        }
//        YxUser user = new YxUser();
//        user.setUid(yxUser.getUid());
        yxUser.setNowMoney(BigDecimal.valueOf(newMoney));
        saveOrUpdate(yxUser);

        /*TemplateBean templateBean = TemplateBean.builder()
                .orderId(param.getMoney().toString())
                .price(yxUser.getNowMoney().toString())
                .uid(yxUser.getUid())
                .templateType(TemplateListenEnum.TYPE_10.getValue())
                .time(DateUtil.formatDateTime(new Date()))
                .payType(type)
                .build();
        publisher.publishEvent(new TemplateEvent(this,templateBean));*/
    }

    /**
     * 增加佣金
     * @param price 金额
     * @param uid 用户id
     */
    @Override
    public void incBrokeragePrice(BigDecimal price, Long uid) {
        yxUserMapper.incBrokeragePrice(price,uid);
    }

    /**
     * 增加复购金额
     * @param price 金额
     * @param uid 用户id
     */
    @Override
    public void incBalancePrice(BigDecimal price, Long uid) {
        yxUserMapper.incBalancePrice(price,uid);
    }

    /**
     * 减少复购金额
     * @param price 金额
     * @param uid 用户id
     */
    @Override
    public void decBalancePrice(BigDecimal price, Long uid) {
        yxUserMapper.decBalancePrice(price,uid);
    }

    /**
     * 统计分销人员
     * @param uid uid
     * @return map
     */
    @Override
    public JSONObject getParentUsers(Long uid) {
        log.info("=====uid====="+uid);
        List<HashMap<String,Object>> userList =new ArrayList<HashMap<String,Object>>();
        try {
            userList = yxUserMapper.getParentUsers(uid);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new YshopException("无数据");
        }

        String resultStr = "{";
        for(int i = 0;i<userList.size();i++) {
            Map item = userList.get(i);
            if(i==0) {
                resultStr+=i+":{'spread_count':'"+item.get("spread_count")+"','normal_count':'"+item.get("normal_count")+"','vip_count':'"+item.get("vip_count")+"','id':'"+item.get("uid")+"','spread_uid':'"+item.get("spread_uid")+"','userName':'"+item.get("userName")+"','member_level':'"+item.get("level")+"','whether_slim':'"+item.get("whether_slim")+"'}";
            }else {
                resultStr+=","+i+":{'spread_count':'"+item.get("spread_count")+"','normal_count':'"+item.get("normal_count")+"','vip_count':'"+item.get("vip_count")+"','id':'"+item.get("uid")+"','spread_uid':'"+item.get("spread_uid")+"','userName':'"+item.get("userName")+"','member_level':'"+item.get("level")+"','whether_slim':'"+item.get("whether_slim")+"'}";
            }
        }
        resultStr += "}";
        JSONObject jsonObj = JSONObject.parseObject(resultStr, Feature.OrderedField);
        //JSONObject json = new JSONObject();
        Map<String,Integer> map = new LinkedHashMap<>(2);
        //map.put("first",countOne); //一级
        //map.put("second",countTwo);//二级

        return jsonObj;
    }

    /**
     * 统计分销人员
     * @param uid uid
     * @return map
     */
    @Override
    public JSONObject getParentByUserid(Long uid,Integer level) {
        List<HashMap<String,Object>> result = yxUserMapper.getParentByUserid(uid,level);
        String resultStr = "";
        if(result.size()>0) {
            Map item = result.get(0);
            resultStr="{'parent_id':'"+item.get("parent_id")+"','member_id':'"+item.get("member_id")+"'}";
        }else{
            resultStr="{'parent_id':'"+""+"','member_id':'"+""+"'}";
        }
        //resultStr += "}";
        log.info("=====resultStr====="+resultStr);
        JSONObject jsonObj = JSONObject.parseObject(resultStr);
        log.info("=====jsonObj====="+jsonObj);
        //JSONObject json = new JSONObject();
        Map<String,Integer> map = new LinkedHashMap<>(2);
        //map.put("first",countOne); //一级
        //map.put("second",countTwo);//二级

        return jsonObj;
    }

    /**
     * 获取当前用户的同级直属人数
     * @param uid uid
     * @return map
     */
    @Override
    public String getChildrens4Main(Long uid,Integer level) {
        String result = yxUserMapper.getChildrens4Main(uid,level);
        return result;
    }

    /**
     * 设置所有上级id到path字段
     * @param uid uid
     */
    @Override
    public void initPath(long uid,String spread) {
        if(StrUtil.isBlank(spread) || !NumberUtil.isNumber(spread)) {
            return;
        }
        yxUserMapper.initPath(uid);
    }

    /**
     * 查看授权调整直属下级级别列表
     * @param uid 用户id
     * @param page page
     * @param limit limit
     * @return list
     */
    @Override
    public List<YxUserQueryVo> userThroughList(Long uid,int page, int limit) {
        LambdaQueryWrapper<YxUser> wrapper= new LambdaQueryWrapper<>();
        if(uid != null) {
            wrapper.eq(YxUser::getThroughUid,uid);
        }

        wrapper.orderByDesc(YxUser::getUid);
        Page<YxUser> pageModel = new Page<>(page, limit);
        IPage<YxUser> pageList = yxUserMapper.selectPage(pageModel,wrapper);
        List<YxUserQueryVo> list = generator.convert(pageList.getRecords(),YxUserQueryVo.class);

        return list.stream()
                .collect(Collectors.toList());

    }

    /**
     * 抽奖活动结束次数清0
     */
    @Override
    public void updatePrizeCount(Long prizeId) {

        yxUserMapper.updatePrizeCount();//将用户的抽奖次数清0
        yxUserMapper.updatePrizeStatus(prizeId);//将未兑换的抽奖记录变成已过期状态
    }

    /**
     * 直通车赠送名额
     * @param param UserMoneyDto
     */
    @Override
    public void updateThrough(UserThroughDto param) {
        Integer directionType =param.getDirectionType();
        String direction ="增加";
        if(directionType.intValue() ==1){
            yxUserMapper.updateThroughDec(param.getVipHroughTrain(),param.getGoldHroughTrain(),
                    param.getDiamondsHroughTrain(),param.getUid());
            direction ="减少";
        }else{
            yxUserMapper.updateThroughInc(param.getVipHroughTrain(),param.getGoldHroughTrain(),
                    param.getDiamondsHroughTrain(),param.getUid());
        }
        String mark =direction+"店主数量:"+param.getVipHroughTrain()+direction+"经理数量:"+param.getGoldHroughTrain()
                +direction+"合伙人数量:"+param.getDiamondsHroughTrain();
        billService.expend(param.getUid(), "直通车赠送名额",
                BillDetailEnum.CATEGORY_3.getValue(),
                BillDetailEnum.TYPE_11.getValue(),
                0, 0, mark);

    }

    /**
     * 统计分销人员
     * @param uid uid
     * @return map
     */
    @Override
    public List<HashMap<String,Object>> getParentByUserId(Long uid,Integer level) {
        List<HashMap<String,Object>> result = yxUserMapper.getParentByUserId(uid,level);
        return result;
    }

    @Override
    public List<HashMap<String,Object>> getParentByBossUserId(Long uid,Integer level) {
        List<HashMap<String,Object>> result = yxUserMapper.getParentByBossUserId(uid,level);
        return result;
    }

    /**
     * 统计数据
     * @param param
     * @return map
     */
    @Override
    public Map<String,Object> totalDatas(UserTotalDatasDto param) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        Date date =new Date();
        String beginMonth =sdf.format(date)+"-01";
        String endMonth =sdf.format(date)+"-12";
        if(ObjectUtil.isNotEmpty(param.getBeginMonth())){
            beginMonth =param.getBeginMonth();
        }
        if(ObjectUtil.isNotEmpty(param.getEndMonth())){
            endMonth =param.getEndMonth();
        }
        List<TotalDataQueryVo> list =yxUserMapper.totalDatas(beginMonth,endMonth);
        List monthArr =new ArrayList();
        List orderArr =new ArrayList();
        List turnoverArr =new ArrayList();
        List userArr =new ArrayList();
        Map<String,Object> map = Maps.newHashMap();
        if(list.size()>0){
            for(int i=0;i<list.size();i++){
                TotalDataQueryVo vo =list.get(i);
                monthArr.add(vo.getMonthArr());
                orderArr.add(vo.getOrderArr());
                turnoverArr.add(vo.getTurnoverArr());
                userArr.add(vo.getUserArr());
            }
        }
        map.put("monthArr",monthArr);
        map.put("orderArr",orderArr);
        map.put("turnoverArr",turnoverArr);
        map.put("userArr",userArr);
        return map;
    }

    /**
     * 增加复购金额
     * @param uid 用户id
     */
    @Override
    public void incGiveVip(Long uid,Integer giveActivityCount) {
        yxUserMapper.incGiveVip(uid,giveActivityCount);
    }
}
